﻿using Sunny.UI;
using System;
using System.Linq;
using System.Text.RegularExpressions;

namespace DevelopTool.Common
{
    /// <summary>
    /// 字符串帮助类
    /// </summary>
    public static class StringHelper
    {
        /// <summary>
        /// 截取中间字符串
        /// </summary>
        /// <param name="text">需要截取的字符串（原始字符串）</param>
        /// <param name="startStr">开始字符串</param>
        /// <param name="lastStr">结束字符串</param>
        /// <param name="type">类型</param>
        /// <returns></returns>
        public static string GetContent(this string text, string startStr, string lastStr, int type)
        {
            if (text.ToLower().IndexOf(startStr.ToLower()) >= 0)
            {
                if (text.ToLower().IndexOf(lastStr.ToLower()) >= 0)
                {
                    switch (type)
                    {
                        //左右都截取（都取前面）（包含关键字）        
                        case 1:
                            text = text.Substring(text.ToLower().IndexOf(startStr.ToLower()), text.Length - text.ToLower().IndexOf(startStr.ToLower()));
                            text = text.Substring(0, text.ToLower().IndexOf(lastStr.ToLower()) + lastStr.Length); break;
                        //左右都截取（都取前面）（去除关键字）                     
                        case 2:
                            text = text.Substring(text.ToLower().IndexOf(startStr.ToLower()) + startStr.Length, text.Length - text.ToLower().IndexOf(startStr.ToLower()) - startStr.Length);
                            text = text.Substring(0, text.ToLower().IndexOf(lastStr.ToLower())); break;
                        //左右都截取（都取后面）（包含关键字）                     
                        case 3:
                            text = text.Substring(text.ToLower().LastIndexOf(startStr.ToLower()), text.Length - text.ToLower().LastIndexOf(startStr.ToLower()));
                            text = text.Substring(0, text.ToLower().LastIndexOf(lastStr.ToLower()) + lastStr.Length); break;
                        //左右都截取（都取后面）（去除关键字）                     
                        case 4:
                            text = text.Substring(text.ToLower().LastIndexOf(startStr.ToLower()) + startStr.Length, text.Length - text.ToLower().LastIndexOf(startStr.ToLower()) - startStr.Length);
                            text = text.Substring(0, text.ToLower().LastIndexOf(lastStr.ToLower())); break;
                        //左右都截取（一前一后）（包含关键字）                       
                        case 5:
                            text = text.Substring(text.ToLower().IndexOf(startStr.ToLower()), text.Length - text.ToLower().IndexOf(startStr.ToLower()));
                            text = text.Substring(0, text.ToLower().LastIndexOf(lastStr.ToLower()) + lastStr.Length); break;
                        //左右都截取（一前一后）（去除关键字）                       
                        case 6:
                            text = text.Substring(text.ToLower().IndexOf(startStr.ToLower()) + startStr.Length, text.Length - text.ToLower().IndexOf(startStr.ToLower()) - startStr.Length);
                            text = text.Substring(0, text.ToLower().LastIndexOf(lastStr.ToLower())); break;
                        default: text = string.Empty; break;
                    }
                }
                else
                {
                    switch (type)
                    {
                        //只往左截取（取前面的）（包含关键字）            
                        case 7: text = text.Substring(0, text.ToLower().IndexOf(startStr.ToLower()) + startStr.Length); break;
                        //只往左截取（取前面的）（去除关键字）                     
                        case 8: text = text.Substring(0, text.ToLower().IndexOf(startStr.ToLower())); break;
                        //只往左截取（取后面的）（包含关键字）                    
                        case 9: text = text.Substring(0, text.ToLower().LastIndexOf(startStr.ToLower()) + startStr.Length); break;
                        //只往左截取（取后面的）（去除关键字）                   
                        case 10: text = text.Substring(0, text.ToLower().LastIndexOf(startStr.ToLower())); break;
                        //只往右截取（取前面的）（包含关键字）                     
                        case 11: text = text.Substring(text.ToLower().IndexOf(startStr.ToLower()), text.Length - text.ToLower().IndexOf(startStr.ToLower())); break;
                        //只往右截取（取前面的）（去除关键字）                   
                        case 12: text = text.Substring(text.ToLower().IndexOf(startStr.ToLower()) + startStr.Length, text.Length - text.ToLower().IndexOf(startStr.ToLower()) - startStr.Length); break;
                        //只往右截取（取后面的）（包含关键字）                     
                        case 13: text = text.Substring(text.ToLower().LastIndexOf(startStr.ToLower()), text.Length - text.ToLower().LastIndexOf(startStr.ToLower())); break;
                        //只往右截取（取后面的）（去除关键字）                      
                        case 14: text = text.Substring(text.ToLower().LastIndexOf(startStr.ToLower()) + startStr.Length, text.Length - text.ToLower().LastIndexOf(startStr.ToLower()) - startStr.Length); break;
                        default: text = string.Empty; break;
                    }
                }
            }
            else
            {
                text = string.Empty;
            }
            return text;
        }

        /// <summary>
        /// 判断字符串中是否包含中文
        /// </summary>
        /// <param name="str">需要判断的字符串</param>
        /// <returns>判断结果</returns>
        public static bool HasChinese(string str)
        {
            return Regex.IsMatch(str, @"[\u4e00-\u9fa5]");
        }

        /// <summary>
        /// 判断字符串中是否包含英文字母
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool HasEnglish(string str)
        {
            return Regex.IsMatch(str, "[A-Za-z]");
        }

        /// <summary>
        /// 判断字符串中是否包含数字
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool HasNumber(string str)
        {
            return Regex.IsMatch(str, "[0-9]");
        }

        /// <summary>
        /// URL编码
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string UrlEncode(string url)
        {
            return System.Web.HttpUtility.UrlEncode(url);
        }

        /// <summary>
        /// URL解码
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string UrlDecode(string url)
        {
            return System.Web.HttpUtility.UrlDecode(url);
        }

        /// <summary>
        /// 删除最后一个字符
        /// </summary>
        /// <param name="input"></param>
        /// <param name="text"></param>
        /// <returns></returns>
        public static string RemoveLastStr(this string input, string text)
        {
            int lastIndex = input.LastIndexOf(text);
            if (lastIndex != -1)
            {
                return input.Remove(lastIndex, text.Length);
            }
            return input;
        }

        #region 计算字符数量

        /// <summary>
        /// 正则表达式匹配任何中文字符数量
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static int GetChineseCharactersCount(string input)
        {
            // 正则表达式匹配任何中文字符  
            var regex = new Regex(@"[\u4e00-\u9fff]+");

            // 找到所有匹配项  
            MatchCollection matches = regex.Matches(input);

            // 计算匹配项的总长度（因为每个匹配项可能包含多个字符）  
            int chars = 0;
            foreach (Match match in matches)
            {
                chars += match.Length;
            }
            return chars;
        }

        /// <summary>
        /// 正则表达式匹配任何英文字符数量
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static int GetEnglishCharactersCount(string input)
        {
            // 正则表达式匹配任何英文字符  
            var regex = new Regex(@"[A-Za-z]+");

            // 找到所有匹配项  
            MatchCollection matches = regex.Matches(input);

            // 计算匹配项的总长度（因为每个匹配项可能包含多个字符）  
            int chars = 0;
            foreach (Match match in matches)
            {
                chars += match.Length;
            }
            return chars;
        }

        /// <summary>
        /// 正则表达式匹配任何数字字符数量
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static int GetNumberCharactersCount(string input)
        {
            // 正则表达式匹配任何数字字符  
            var regex = new Regex(@"[0-9]+");

            // 找到所有匹配项  
            MatchCollection matches = regex.Matches(input);

            // 计算匹配项的总长度（因为每个匹配项可能包含多个字符）  
            int chars = 0;
            foreach (Match match in matches)
            {
                chars += match.Length;
            }
            return chars;
        }

        /// <summary>
        /// 正则表达式匹配任何符号字符数量
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static int GetSymbolCharactersCount(string input)
        {
            // 正则表达式匹配任何符号字符  
            var regex = new Regex(@"[\p{P}\p{S}]+");

            // 找到所有匹配项  
            MatchCollection matches = regex.Matches(input);

            // 计算匹配项的总长度（因为每个匹配项可能包含多个字符）  
            int chars = 0;
            foreach (Match match in matches)
            {
                chars += match.Length;
            }
            return chars;
        }

        #endregion 计算字符数量


        #region 检查密码强度

        /// <summary>
        /// 检查密码强度
        /// </summary>
        /// <param name="password"></param>
        /// <returns></returns>
        public static int CheckStrength(string password)
        {
            int score = 0;

            // 规则1：密码长度
            if (password.Length >= 8 && password.Length <= 16)
            {
                score++;
            }

            // 规则2：包含数字
            if (Regex.IsMatch(password, @"\d"))
            {
                score++;
            }

            // 规则3：包含大写字母
            if (password.Any(char.IsUpper))
            {
                score++;
            }

            // 规则4：包含小写字母
            if (password.Any(char.IsLower))
            {
                score++;
            }

            // 规则5：包含特殊字符
            if (Regex.IsMatch(password, @"[!@#$%^&*()_+=\[{\]};:<>|./?,-]"))
            {
                score++;
            }

            // 规则6：密码熵
            double entropy = Entropy(password);
            if (entropy >= 2.5)
            {
                score++;
            }

            // 规则7：键盘布局
            if (IsSequential(password))
            {
                score--;
            }

            // 确保分数在0到5之间
            return Math.Min(5, Math.Max(0, score));
        }

        /// <summary>
        /// 计算密码的信息熵
        /// </summary>
        /// <param name="password"></param>
        /// <returns></returns>
        static double Entropy(string password)
        {
            // 统计每个字符的出现频率
            var charFrequency = password.GroupBy(c => c).ToDictionary(g => g.Key, g => (double)g.Count() / password.Length);
            // 计算信息熵
            return -charFrequency.Values.Sum(p => p * Math.Log(p, 2));
        }

        /// <summary>
        /// 检查密码中是否有连续的字符
        /// </summary>
        /// <param name="password"></param>
        /// <returns></returns>
        static bool IsSequential(string password)
        {
            for (int i = 0; i < password.Length - 2; i++)
            {
                // 判断是否有连续的三个字符
                if ((password[i + 1] == password[i] + 1 && password[i + 2] == password[i] + 2) ||
                    (password[i + 1] == password[i] - 1 && password[i + 2] == password[i] - 2))
                {
                    return true;
                }
            }
            return false;
        }

        #endregion 检查密码强度

        /// <summary>
        /// 辅助方法：从命令行参数中获取指定名称的值，类似Action=haha
        /// </summary>
        /// <param name="args"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static string GetCommandLineArgument(string[] args, string name)
        {
            foreach (var arg in args)
            {
                if (arg.StartsWith($"{name}="))
                {
                    return arg.Substring(name.Length + 1);
                }
            }
            return null;
        }

        /// <summary>
        /// 获取字符串长度，考虑中文字符情况
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static int GetStrLength(string str)
        {
            return System.Text.Encoding.Default.GetBytes(str).Length;
        }

        /// <summary>
        /// 加密并压缩字符串
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string EncryptAndCompress(this string input)
        {
            input = input.GZipCompress();//先压缩
            return input.DesEncrypt(GlobalData.AppName_en);//再加密
        }

        /// <summary>
        /// 解密并解压缩字符串
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string DecryptAndDecompress(this string input)
        {
            input = input.DesDecrypt(GlobalData.AppName_en);//先解密
            return input.GZipDecompress();//再解压缩
        }

    }
}
